<?php


namespace addon\hotel\model;

use addon\hotel\model\Room as RoomModel;
use app\model\BaseModel;
use app\model\hotel\Baoyu;
use app\model\hotel\Hotel;
use app\model\member\MemberAccount;
use app\model\member\MemberLevel;
use app\model\order\Config;
use app\model\system\Cron;
use Exception;
use app\model\system\Pay;

class OrderCommon extends BaseModel
{
    // 订单待付款
    const ORDER_CREATE = 0;

    // 订单代入驻
    const ORDER_PAY = 1;

    //订单已入驻
    const ORDER_TAKE_DELIVERY = 4;

    // 订单已结算完成
    const ORDER_COMPLETE = 10;

    // 订单已关闭
    const ORDER_CLOSE = -1;

    public $order_status = [
        self::ORDER_CREATE => [
            'status' => self::ORDER_CREATE,
            'name' => '待支付',
            'is_allow_refund' => 0,
            'icon' => 'upload/uniapp/order/order-icon.png',
            'action' => [
                [
                    'action' => 'orderClose',
                    'title' => '关闭订单',
                    'color' => ''
                ]
            ],
            'member_action' => [
                [
                    'action' => 'orderClose',
                    'title' => '关闭订单',
                    'color' => ''
                ],
                [
                    'action' => 'orderPay',
                    'title' => '支付',
                    'color' => ''
                ],
            ],
            'color' => ''
        ],
        self::ORDER_PAY => [
            'status' => self::ORDER_PAY,
            'name' => '待入驻',
            'is_allow_refund' => 0,
            'icon' => 'upload/uniapp/order/order-icon-send.png',
            'action' => [

            ],
            'member_action' => [

            ],
            'color' => ''
        ],
        self::ORDER_TAKE_DELIVERY => [
            'status' => self::ORDER_TAKE_DELIVERY,
            'name' => '已入驻',
            'is_allow_refund' => 0,
            'icon' => 'upload/uniapp/order/order-icon-send.png',
            'action' => [

            ],
            'member_action' => [

            ],
            'color' => ''
        ],
        self::ORDER_COMPLETE => [
            'status' => self::ORDER_COMPLETE,
            'name' => '已完成',
            'is_allow_refund' => 1,
            'icon' => 'upload/uniapp/order/order-icon-received.png',
            'action' => [
            ],
            'member_action' => [

            ],
            'color' => ''
        ],
        self::ORDER_CLOSE => [
            'status' => self::ORDER_CLOSE,
            'name' => '已关闭',
            'is_allow_refund' => 0,
            'icon' => 'upload/uniapp/order/order-icon-close.png',
            'action' => [

            ],
            'member_action' => [

            ],
            'color' => ''
        ],
    ];

    public $pay_type = [
        //'ONLINE_PAY' => '在线支付',
        'BALANCE' => '余额支付',
        //'OFFLINE_PAY' => '线下支付'
    ];

    /**
     * 获取支付方式
     */
    public function getPayType()
    {
        //获取订单基础的其他支付方式
        $pay_type = $this->pay_type;
        //获取当前所有在线支付方式
        $onlinepay = event('PayType', []);
        if (!empty($onlinepay)) {
            foreach ($onlinepay as $k => $v) {
                $pay_type[ $v[ 'pay_type' ] ] = $v[ 'pay_type_name' ];
            }
        }
        return $pay_type;
    }

    /**
     * 订单线下支付
     * @param $order_id
     * @return array
     */
    public function orderOfflinePay($out_trade_no)
    {
        model('hotel_order')->startTrans();
        try {

            $pay_model = new Pay();
            $result = $pay_model->onlinePay($out_trade_no, "OFFLINE_PAY", '', '');
            if ($result[ "code" ] < 0) {
                model('hotel_order')->rollback();
                return $result;
            }
            model('hotel_order')->commit();
            return $result;
        } catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    //到达离店日期12点释放库存
    public function orderRoomIncStock($order_id)
    {
        $order_info = model("hotel_order")->getInfo(['order_id'=>$order_id], "order_id,hotel_id,pay_status,member_id,order_no,mobile,order_status,use_point,is_lock,balance_money,baoyu_order_id,room_id,room_num");

        if ($order_info[ "order_status" ] == -1) {
            return $this->success();
        }

        $goods_stock_model = new RoomStock();
        //if ($order_info[ "refund_status" ] != $order_refund_model::REFUND_COMPLETE) {
        $item_param = [
            "room_id" => $order_info[ "room_id" ],
            "room_num" => $order_info[ "room_num" ],
        ];
        //返还库存
        $res = $goods_stock_model->incStock($item_param);

        return $this->success();
    }

    /**
     * 订单关闭
     * @param $order_id
     * @return array
     */
    public function orderClose($condition)
    {
        model('hotel_order')->startTrans();
        try {

            $order_info = model("hotel_order")->getInfo($condition, "order_id,hotel_id,pay_status,member_id,order_no,mobile,order_status,use_point,is_lock,balance_money,baoyu_order_id,room_id,room_num");

            if ($order_info[ "order_status" ] == -1) {
                model('hotel_order')->commit();
                return $this->success();
            }

            $hotel_model = new Hotel();

            $hotel_info = $hotel_model->getHotelInfo([['hotel_id','=',$order_info['hotel_id']]],'hotel_id,hotel_name,status,direct');

            $hotel_info = $hotel_info['data'];

            /*if ($hotel_info['direct']==1){
                $baoyu_model = new Baoyu();
                //取消宝寓订单
                $res = $baoyu_model->cancelOrder($order_info['baoyu_order_id']);
                if ($res['data']['state']!=0){
                    return $this->error('', '宝寓订单取消失败');
                }
            }*/
            /*$goods_stock_model = new RoomStock();

            $item_param = [
                "room_id" => $order_info[ "room_id" ],
                "room_num" => $order_info[ "room_num" ],
            ];
            //返还库存
            $goods_stock_model->incStock($item_param);*/


            $order_id = $order_info[ 'order_id' ];
            $lock_result = $this->verifyOrderLock($order_info);

            if ($lock_result[ "code" ] < 0) {
                model('hotel_order')->rollback();
                return $lock_result;
            }

            $order_data = [
                'order_status' => self::ORDER_CLOSE,
                'order_status_name' => $this->order_status[ self::ORDER_CLOSE ][ "name" ],
                'order_status_action' => json_encode($this->order_status[ self::ORDER_CLOSE ], JSON_UNESCAPED_UNICODE),
                'close_time' => time(),
                'is_enable_refund' => 0
            ];
            model('hotel_order')->update($order_data, [ [ 'order_id', "=", $order_id ] ]);

            //循环订单项 依次返还库存

            $is_exist_refund = false;//是否存在退款

            //平台优惠券

            //平台余额  退还余额
            if (!$is_exist_refund) {//因为订单完成后  只有全部退款完毕订单才会关闭
                if ($order_info[ "balance_money" ] > 0) {
                    $member_account_model = new MemberAccount();
                    $member_account_model->addMemberAccount($order_info[ "member_id" ], "balance", $order_info[ "balance_money" ], "order", "余额返还", "订单关闭,返还余额:" . $order_info[ "balance_money" ]);
                }

                // 订单关闭返还积分
                if ($order_info['use_point'] > 0) {
                    $member_account_model = new MemberAccount();
                    $result = $member_account_model->addMemberAccount($order_info["member_id"], "point", $order_info['use_point'], "refund", $order_id, "酒店订单关闭,返还积分:" . $order_info['use_point']);
                }
            }
            //订单关闭后操作
            model('hotel_order')->commit();

            return $this->success();
        } catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    //入驻
    public function orderConfirm($condition)
    {
        model('hotel_order')->startTrans();

        try {
            $order_info = model("hotel_order")->getInfo($condition, "*");
            if ($order_info[ "order_status" ] == 4) {
                model('hotel_order')->commit();
                return $this->success();
            }

            $order_data = [
                //'order_status' => self::ORDER_COMPLETE,
                //'order_status_name' => $this->order_status[ self::ORDER_COMPLETE ][ "name" ],
                //'order_status_action' => json_encode($this->order_status[ self::ORDER_COMPLETE ], JSON_UNESCAPED_UNICODE),
                'order_status' => self::ORDER_TAKE_DELIVERY,
                'order_status_name' => $this->order_status[ self::ORDER_TAKE_DELIVERY ][ "name" ],
                'order_status_action' => json_encode($this->order_status[ self::ORDER_TAKE_DELIVERY ], JSON_UNESCAPED_UNICODE),
                'confirm_time' => time(),
                'is_confirm' => 1,
                //'finish_time' => time(),
            ];

            //处理酒店抽佣后的金额

            model('hotel_order')->update($order_data, $condition);


            $execute_time = strtotime($order_info['end_date'])+86400;
            //设置订单自动完成事件

            $cron_model = new Cron();
            $result = $cron_model->addCron(1, 0, "订单自动完成", "CronHotelOrderComplete", $execute_time, $order_info['order_id']);

            //event("HotelOrderComplete", $order_info);
            model('hotel_order')->commit();
            return $this->success();
        }  catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    //完成
    public function orderComplete($condition)
    {
        model('hotel_order')->startTrans();

        try {
            $order_info = model("hotel_order")->getInfo($condition, "*");
            if ($order_info[ "order_status" ] == 10) {
                model('hotel_order')->commit();
                return $this->success();
            }

            $order_data = [
                'order_status' => self::ORDER_COMPLETE,
                'order_status_name' => $this->order_status[ self::ORDER_COMPLETE ][ "name" ],
                'order_status_action' => json_encode($this->order_status[ self::ORDER_COMPLETE ], JSON_UNESCAPED_UNICODE),
                'finish_time' => time(),
            ];

            //处理酒店抽佣后的金额

            model('hotel_order')->update($order_data, $condition);

            event("HotelOrderComplete", $order_info);
            model('hotel_order')->commit();
            return $this->success();
        }  catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    public function orderRefund($data,$condition)
    {
        model('hotel_order')->startTrans();

        $refund_total_real_money = $data['order_money'];
        try {
            $order_info = model("hotel_order")->getInfo($condition, "*");

            if ($refund_total_real_money > $order_info[ "order_money" ]) {
                model('hotel_order')->rollback();
                return $this->error([], "退款金额不能大于订单总金额");
            }
            //实际执行转账 (存在余额支付的话   退款一部分余额  退还一部分实际金额)  //订单退款退回余额积分等操作

            $refund_pay_money = 0;
            $refund_balance_money = 0;
            if ($data['refund_type']==2){
                if ($order_info['pay_type']=='BALANCE'){
                    $refund_balance_money = $data['refund_money'];
                } else {
                    $refund_pay_money = $data['refund_money'];
                }
            } else {
                $refund_pay_money = $order_info[ "pay_money" ];
                if ($order_info[ "balance_money" ] > 0) {
                    $refund_balance_money = $order_info[ "balance_money" ];
                } else {
                    $refund_balance_money = 0;
                    $refund_pay_money = $order_info[ "pay_money" ];
                }
            }

            $pay_model = new Pay();
            $refund_no = $pay_model->createRefundNo($order_info[ 'order_id' ]);

            //退还直接支付的金额
            if ($refund_pay_money > 0) {
                $pay_model = new Pay();
                $refund_result = $pay_model->refund($refund_no, $refund_pay_money, $order_info[ "out_trade_no" ], '', $order_info[ "pay_money" ], $order_info[ "hotel_id" ], 1);

                if ($refund_result[ "code" ] < 0) {
                    model('hotel_order')->rollback();
                    return $refund_result;
                }
            }

            //退款余额
            if ($refund_balance_money > 0) {
                $member_account_model = new MemberAccount();
                $balance_result = $member_account_model->addMemberAccount($order_info[ "member_id" ], "balance_money", $refund_balance_money, "refund", "余额返还", "酒店订单退款,返还余额:" . $refund_balance_money);
                if ($balance_result[ "code" ] < 0) {
                    model('hotel_order')->rollback();
                    return $balance_result;
                }
            }

            $order_data = [
                'refund_no'=>$refund_no,
                'is_enable_refund' => 0
            ];

            if ($data['refund_type']==1){
                //退全款
                $order_data['order_status'] = self::ORDER_CLOSE;
                $order_data['order_status_name'] =  $this->order_status[ self::ORDER_CLOSE ][ "name" ];
                $order_data['order_status_action'] = json_encode($this->order_status[ self::ORDER_CLOSE ], JSON_UNESCAPED_UNICODE);
                $order_data['close_time'] = time();
                $order_data['total_refund_money'] = $data['order_money'];

            } else {
                if ($data['is_cancel']==1){
                    $order_data['order_status'] = self::ORDER_CLOSE;
                    $order_data['order_status_name'] =  $this->order_status[ self::ORDER_CLOSE ][ "name" ];
                    $order_data['order_status_action'] = json_encode($this->order_status[ self::ORDER_CLOSE ], JSON_UNESCAPED_UNICODE);
                    $order_data['close_time'] = time();
                    //$order_data['total_refund_money'] = $data['order_money'];
                }
                $order_data['total_refund_money'] = $order_info['total_refund_money']+$data['refund_money'];
            }

            /*if (isset($order_data['order_status'])){
                $goods_stock_model = new RoomStock();

                $item_param = [
                    "room_id" => $order_info[ "room_id" ],
                    "room_num" => $order_info[ "room_num" ],
                ];
                //返还库存
                $res = $goods_stock_model->incStock($item_param);
            }*/

            //退款重新计算抽成和店铺的金额
            $hotel_info = model('hotel')->getInfo(['hotel_id'=>$order_info['hotel_id']],'commission_rate');
            //$goods_money = $order_info[ 'real_room_money' ];
            $goods_money = $order_info[ "order_money" ]-$order_data['total_refund_money'];
            $platform_money = round(floor($goods_money * $hotel_info[ 'commission_rate' ]) / 100, 2);
            $hotel_money = round(floor(( $goods_money - $platform_money ) * 100) / 100, 2);

            $order_data['hotel_money'] = $hotel_money;
            $order_data['platform_money'] = $platform_money;

            $result = model('hotel_order')->update($order_data, [ [ 'order_id', "=", $order_info['order_id'] ] ]);

            model('hotel_order')->commit();

            return $this->success($result);
        } catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }
    }

    //线上支付回调
    public function orderOnlinePay($data)
    {
        model('hotel_order')->startTrans();

        try {
            $out_trade_no = $data[ "out_trade_no" ];
            $pay_type = $data[ 'pay_type' ] ?? 'ONLINE_PAY';

            $pay_type_list = $this->getPayType();

            $order_info = model('hotel_order')->getInfo(['out_trade_no'=>$out_trade_no]);

            if ($order_info[ 'order_status' ] != 0) {
                return $this->error();
            }
            $condition = array (
                [ "order_id", "=", $order_info[ "order_id" ] ],
                [ "order_status", "=", self::ORDER_CREATE ],
            );

            $data = array (
                "order_status" => self::ORDER_PAY,
                "order_status_name" => $this->order_status[ self::ORDER_PAY ][ "name" ],
                "pay_status" => 1,
                "order_status_action" => json_encode($this->order_status[ self::ORDER_PAY ], JSON_UNESCAPED_UNICODE),
                "pay_time" => time(),
                "pay_type" => $pay_type,
                "pay_type_name" => $pay_type_list[ $pay_type ],
                "is_enable_refund" => 1,
            );

            $result = model("hotel_order")->update($data, $condition);

            $order = model("hotel_order")->getInfo([['order_id', '=', $order_info["order_id"]]], '*');

            //$inc_stock_time = strtotime($order_info['end_date'].' 12:00');
            //到离店日期 加上库存
            //$cron_model = new Cron();
            //$cron_model->addCron(1, 0, "酒店订单自动释放库存", "CronHotelRoomIncStock", $inc_stock_time, $order_info["order_id"]);

            event("HotelOrderPay", $order);

            event("HotelFenxiaoOrder", $order);

            model('hotel_order')->commit();

            return $this->success($result);

        } catch (Exception $e) {
            model('hotel_order')->rollback();
            return $this->error('', $e->getMessage());
        }

    }


    /**
     * 会员订单分页列表
     * @param array $condition
     * @param int $page
     * @param int $page_size
     * @param string $order
     * @param string $field
     * @return array
     */
    public function getMemberOrderPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*')
    {
        $order_list = model('hotel_order')->pageList($condition, $field, $order, $page, $page_size);
        if (!empty($order_list[ 'list' ])) {
            foreach ($order_list[ 'list' ] as $k => $v) {
                $action = empty($v[ "order_status_action" ]) ? [] : json_decode($v[ "order_status_action" ], true);
                $member_action = $action[ "member_action" ] ?? [];
                $order_list[ 'list' ][ $k ][ 'action' ] = $member_action;
            }
        }
        return $this->success($order_list);
    }

    /**
     * 获取订单分页列表
     * @param array $condition
     * @param int $page
     * @param int $page_size
     * @param string $order
     * @param string $field
     * @param string $alias
     * @param array $join
     * @param string $oder_goods_field
     * @return array
     */
    public function getOrderPageList($condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = '', $field = '*', $alias = 'a', $join = [], $oder_goods_field = '*')
    {
        $order_list = model('hotel_order')->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
        if (!empty($order_list[ 'list' ])) {
            foreach ($order_list[ 'list' ] as $k => $v) {
                if (!empty($v[ 'member_id' ])) {
                    //购买人信息
                    $member_info = model('member')->getInfo([ 'member_id' => $v[ 'member_id' ] ], 'nickname');
                    $order_list[ 'list' ][ $k ][ 'nickname' ] = $member_info[ 'nickname' ];
                } else {
                    $order_list[ 'list' ][ $k ][ 'nickname' ] = "";
                }
            }
        }

        return $this->success($order_list);
    }

    /**
     * 得到订单基础信息
     * @param $condition
     * @param string $field
     * @return array
     */
    public function getOrderInfo($condition, $field = "*")
    {
        $order_info = model("hotel_order")->getInfo($condition, $field);

        $member_info = model('member')->getInfo([ [ 'member_id', "=", $order_info[ 'member_id' ] ] ], 'nickname');

        $order_info[ 'nickname' ] = $member_info[ 'nickname' ];
        return $this->success($order_info);
    }

    public function getMemberOrderDetail($order_id, $member_id)
    {
        $order_info = model("hotel_order")->getInfo([ [ 'order_id', "=", $order_id ], [ "member_id", "=", $member_id ] ]);

        if (empty($order_info))
            return $this->error([], "当前订单不是本账号的订单!");

        $action = empty($order_info[ "order_status_action" ]) ? [] : json_decode($order_info[ "order_status_action" ], true);
        $member_action = $action[ "member_action" ] ?? [];
        $order_info[ 'action' ] = $member_action;

        $hotel_info = model('hotel')->getInfo(['hotel_id'=>$order_info['hotel_id']],'latitude,longitude,full_address,address,telphone,direct,hotel_id,hotel_name,hotel_img,hotel_level');
        $order_info[ 'hotel_info' ] = $hotel_info;

        $room_model = new RoomModel();

        $condition = [
            ['room_id','=',$order_info['room_id']],
        ];

        $info = $room_model->getNewRoomInfo($condition);
        $order_info[ 'room_info' ] = $info['data'];

        $room_type = model('hotel_room_type')->getInfo(['baoyu_type_id'=>$info['data']['type_id']]);
        $order_info['room_type_info'] = $room_type;
        return $this->success($order_info);
    }

    /**
     * 得到订单数量
     * @param $condition
     * @return array
     */
    public function getOrderCount($condition)
    {
        $res = model("hotel_order")->getCount($condition);
        return $this->success($res);
    }

    /**
     * 验证订单锁定状态
     * @param $param
     * @return array
     */
    public function verifyOrderLock($param)
    {
        if (!is_array($param)) {
            $order_info = model("hotel_order")->getInfo([ [ "order_id", "=", $param ] ], "is_lock");
        } else {
            $order_info = $param;
        }
        if ($order_info[ "is_lock" ] == 1) {//判断订单锁定状态
            model('hotel_order')->rollback();
            return $this->error('', "ORDER_LOCK");
        } else {
            return $this->success();
        }
    }

}